package io.shuttle.mbe.api

import io.shuttle.mbe.api.annotation.ChromeMinVersion
import io.shuttle.mbe.api.types.Value1Function
import io.shuttle.mbe.api.types.VoidFunction
import io.shuttle.mbe.core.Promise

////////////////////
// SidePanel
////////////////////
/**
 * Use the `Browser.sidePanel` API to host content in the browser's side panel alongside the main content of a webpage.
 *
 * Permissions: "sidePanel"
 * @since Chrome 114, MV3
 */
@ChromeMinVersion(114)
interface SidePanel {
    /**
     * Returns the active panel configuration.
     * Promises are supported in Manifest V3 and later, but callbacks are provided for backward compatibility.
     * You cannot use both on the same function call.
     * The promise resolves with the same type that is passed to the callback.
     */
    fun getOptions(
        options: GetPanelOptions,
        callback: Value1Function<PanelOptions>? = null
    ): Promise<PanelOptions>

    /**
     * Returns the extension's current side panel behavior.
     * Promises are supported in Manifest V3 and later, but callbacks are provided for backward compatibility.
     * You cannot use both on the same function call.
     * The promise resolves with the same type that is passed to the callback.
     */
    fun getPanelBehavior(callback: Value1Function<PanelBehavior>? = null): Promise<PanelBehavior>

    /**
     * @since Chrome 116
     * Opens the side panel for the extension. This may only be called in response to a user action.
     * Promises are supported in Manifest V3 and later, but callbacks are provided for backward compatibility.
     * You cannot use both on the same function call.
     * The promise resolves with the same type that is passed to the callback.
     */
    fun open(options: OpenOptions, callback: VoidFunction? = null): Promise<Void>

    /**
     * Configures the side panel.
     * Promises are supported in Manifest V3 and later, but callbacks are provided for backward compatibility.
     * You cannot use both on the same function call.
     * The promise resolves with the same type that is passed to the callback.
     */
    fun setOptions(options: PanelOptions, callback: VoidFunction? = null): Promise<Void>

    /**
     * Configures the extension's side panel behavior. This is an upsert operation.
     * Promises are supported in Manifest V3 and later, but callbacks are provided for backward compatibility.
     * You cannot use both on the same function call.
     * The promise resolves with the same type that is passed to the callback.
     */
    fun setPanelBehavior(behavior: PanelBehavior, callback: VoidFunction? = null): Promise<Void>

    /**
     * If specified, the side panel options for the given tab will be returned.
     * Otherwise, returns the default side panel options (used for any tab that doesn't have specific settings).
     */
    data class GetPanelOptions(var tabId: Number?)

    @ChromeMinVersion(116)
    data class OpenOptions(
        /** The tab in which to open the side panel.
         * If the corresponding tab has a tab-specific side panel, the panel will only be open for that tab.
         * If there is not a tab-specific panel, the global panel will be open in the specified tab and any other tabs without a currently-open tab- specific panel.
         * This will override any currently-active side panel (global or tab-specific) in the corresponding tab.
         * At least one of this and windowId must be provided. */
        var tabId: Number?,
        /**
         * The window in which to open the side panel.
         * This is only applicable if the extension has a global (non-tab-specific) side panel or tabId is also specified.
         * This will override any currently-active global side panel the user has open in the given window.
         * At least one of this and tabId must be provided.
         */
        var windowId: Number?
    )

    data class PanelBehavior(
        /** Whether clicking the extension's icon will toggle showing the extension's entry in the side panel. Defaults to false. */
        var openPanelOnActionClick: Boolean?
    )

    data class PanelOptions(
        /** Whether the side panel should be enabled. This is optional. The default value is true. */
        var enabled: Boolean?,
        /** The path to the side panel HTML file to use. This must be a local resource within the extension package. */
        var path: String?,
        /**
         * If specified, the side panel options will only apply to the tab with this id.
         * If omitted, these options set the default behavior (used for any tab that doesn't have specific settings).
         * Note: if the same path is set for this tabId and the default tabId, then the panel for this tabId will be a different instance than the panel for the default tabId.
         */
        var tabId: Number?
    )

    data class SidePanelDetails(
        /** Developer specified path for side panel display. */
        var default_path: String
    )
}